package com.gjs.sso.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import com.gjs.common.enums.ImageValidateCodeEnum;
import com.gjs.common.enums.entity.UserOriginEnum;
import com.gjs.common.exception.BizException;
import com.gjs.common.manager.SmsVerifyCode;
import com.gjs.common.manager.response.RspBody;
import com.gjs.common.microservice.api.IUserMicroService;
import com.gjs.common.pojo.dto.user.UserInfoDTO;
import com.gjs.common.pojo.dto.user.UserRegisterDTO;
import com.gjs.common.pojo.dto.user.UserRegisterVO;
import com.google.code.kaptcha.Producer;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;

@Controller
@SessionAttributes("authorizationRequest")//必须配置
@RequiredArgsConstructor
@Slf4j
@RefreshScope
public class OauthController {

    @DubboReference
    private IUserMicroService userMicroService;

    private final SmsVerifyCode smsVerifyCode;

    private final Producer captchaProducer;

    @Value("${sso-index}")
    private String ssoIndex;

    @GetMapping("/")
    public String index() {
        return "redirect:" + ssoIndex;
    }

    // 自定义登录页
    @GetMapping(value = {"/login"})
    public String login() {
        return "login";
    }

    // 图形验证码
    @RequestMapping("/image_validate_code")
    public void imageCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 生成验证码
        String capText = captchaProducer.createText();
        // 字符串把它放到session中
        request.getSession().setAttribute(ImageValidateCodeEnum.LOGIN_IMG_VALID_CODE.toString(), capText);
        // 向客户端写出
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }

    // 自定义授权页
    @RequestMapping("/confirm_access")
    public ModelAndView confirmAccess(Map<String, Object> model, HttpServletRequest request) {
        AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");

        ModelAndView view = new ModelAndView();
        view.setViewName("confirm_access");
        view.addObject("clientId", authorizationRequest.getClientId());
        view.addObject("scopes", authorizationRequest.getScope());

        return view;
    }

    // 注册页
    @GetMapping("/register")
    public String registerPage() {
        return "register_page";
    }

    // 注册页
    @PostMapping("/register")
    public ModelAndView register(UserRegisterVO registerVO) {
        ModelAndView view = new ModelAndView();
        view.setViewName("register_result");

        UserRegisterDTO userRegisterDTO = BeanUtil.copyProperties(registerVO, UserRegisterDTO.class);
        // 设置用户来源
        userRegisterDTO.setOrigin(UserOriginEnum.SSO);

        String errorMessage = null;

        // 校验短信验证码
        if (!smsVerifyCode.verify(SmsVerifyCode.VerifyType.REGISTER, registerVO.getMobile(), registerVO.getSmsVerificationCode())) {
            errorMessage = "验证码错误或已过期";
        }

        try {
            UserInfoDTO userInfoDTO = userMicroService.userRegister(userRegisterDTO);
        } catch (Exception e) {
            errorMessage = e.getMessage();
        }

        // 注入错误信息
        view.addObject("errorMessage", errorMessage);

        return view;
    }

    @GetMapping("/send_login_valid_code")
    @ApiOperation("发送登录短信验证码")
    @ResponseBody
    public RspBody sendLoginValidCode(String mobile) {
        try {
            // 校验是否有效手机号
            Validator.validateMobile(mobile, "无效手机号");

            smsVerifyCode.send(SmsVerifyCode.VerifyType.LOGIN, mobile);
        } catch (Exception e) {
            return RspBody.error(e.getMessage());
        }

        return RspBody.success("成功");
    }

    @GetMapping("/send_register_valid_code")
    @ApiOperation("发送注册短信验证码")
    @ResponseBody
    public RspBody sendRegisterValidCode(String mobile) {
        try {
            // 校验是否有效手机号
            Validator.validateMobile(mobile, "无效手机号");
            // 判断手机号是否已注册过
            if (userMicroService.checkUserExistByMobile(mobile)) {
                throw new BizException("该手机号已注册");
            }
            smsVerifyCode.send(SmsVerifyCode.VerifyType.REGISTER, mobile);
        } catch (Exception e) {
            return RspBody.error(e.getMessage());
        }

        return RspBody.success("成功");
    }
}
